package com.ch_linghu.fanfoudroid;

import java.util.ArrayList;
import java.util.List;

import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.ch_linghu.fanfoudroid.fanfou.SavedSearch;
import com.ch_linghu.fanfoudroid.fanfou.Trend;
import com.ch_linghu.fanfoudroid.http.HttpException;
import com.ch_linghu.fanfoudroid.task.GenericTask;
import com.ch_linghu.fanfoudroid.task.TaskAdapter;
import com.ch_linghu.fanfoudroid.task.TaskListener;
import com.ch_linghu.fanfoudroid.task.TaskParams;
import com.ch_linghu.fanfoudroid.task.TaskResult;
import com.ch_linghu.fanfoudroid.ui.base.BaseActivity;
import com.ch_linghu.fanfoudroid.ui.module.Feedback;
import com.ch_linghu.fanfoudroid.ui.module.FeedbackFactory;
import com.ch_linghu.fanfoudroid.ui.module.FeedbackFactory.FeedbackType;
import com.ch_linghu.fanfoudroid.ui.module.NavBar;
import com.ch_linghu.fanfoudroid.util.TextHelper;
import com.commonsware.cwac.merge.MergeAdapter;

public class SearchActivity extends BaseActivity {

    private static final String TAG = SearchActivity.class.getSimpleName();
    private static final int LOADING = 1;
    private static final int NETWORKERROR = 2;
    private static final int SUCCESS = 3;

    private EditText mSearchEdit;
    private ListView mSearchSectionList;
    private TextView trendsTitle;
    private TextView savedSearchTitle;

    private MergeAdapter mSearchSectionAdapter;
    private SearchAdapter trendsAdapter;
    private SearchAdapter savedSearchesAdapter;

    private ArrayList<SearchItem> trends;
    private ArrayList<SearchItem> savedSearch;
    private String initialQuery;

    private NavBar mNavbar;
    private Feedback mFeedback;

    private GenericTask trendsAndSavedSearchesTask;
    private TaskListener trendsAndSavedSearchesTaskListener = new TaskAdapter() {

        @Override
        public String getName() {
            return "trendsAndSavedSearchesTask";
        }

        @Override
        public void onPreExecute(GenericTask task) {
        }

        @Override
        public void onPostExecute(GenericTask task, TaskResult result) {

            if (result == TaskResult.OK) {
                refreshSearchSectionList(SearchActivity.SUCCESS);
            } else if (result == TaskResult.IO_ERROR) {
                refreshSearchSectionList(SearchActivity.NETWORKERROR);

                Toast.makeText(
                        SearchActivity.this,
                        getResources()
                                .getString(
                                        R.string.login_status_network_or_connection_error),
                        Toast.LENGTH_SHORT).show();
            }

        }

    };

    @Override
    protected boolean _onCreate(Bundle savedInstanceState) {
        Log.d(TAG, "onCreate()...");
        if (super._onCreate(savedInstanceState)) {
            setContentView(R.layout.search);
            mNavbar = new NavBar(NavBar.HEADER_STYLE_SEARCH, this);
            mFeedback = FeedbackFactory.create(this, FeedbackType.PROGRESS);

            initView();
            initSearchSectionList();
            refreshSearchSectionList(SearchActivity.LOADING);
            doGetSavedSearches();
            return true;
        } else {
            return false;
        }
    }

    private void initView() {
        mSearchEdit = (EditText) findViewById(R.id.search_edit);
        mSearchEdit.setOnKeyListener(enterKeyHandler);
        trendsTitle = (TextView) getLayoutInflater().inflate(
                R.layout.search_section_header, null);
        trendsTitle.setText(getResources().getString(R.string.trends_title));
        savedSearchTitle = (TextView) getLayoutInflater().inflate(
                R.layout.search_section_header, null);
        savedSearchTitle.setText(getResources().getString(
                R.string.saved_search_title));
        mSearchSectionAdapter = new MergeAdapter();
        mSearchSectionList = (ListView) findViewById(R.id.search_section_list);
        
        mNavbar.getSearchButton().setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                initialQuery = mSearchEdit.getText().toString();
                startSearch();
            }
        });
    }
    
    @Override
    protected void onResume() {
        Log.d(TAG, "onResume()...");
        super.onResume();
    }

    private void doGetSavedSearches() {
        if (trendsAndSavedSearchesTask != null
                && trendsAndSavedSearchesTask.getStatus() == GenericTask.Status.RUNNING) {
            return;
        } else {
            trendsAndSavedSearchesTask = new TrendsAndSavedSearchesTask();
            trendsAndSavedSearchesTask
                    .setListener(trendsAndSavedSearchesTaskListener);
            trendsAndSavedSearchesTask.setFeedback(mFeedback);
                
            trendsAndSavedSearchesTask.execute();
        }
    }

    private void initSearchSectionList() {
        trends = new ArrayList<SearchItem>();
        savedSearch = new ArrayList<SearchItem>();

        trendsAdapter = new SearchAdapter(this);
        savedSearchesAdapter = new SearchAdapter(this);

        mSearchSectionAdapter.addView(savedSearchTitle);
        mSearchSectionAdapter.addAdapter(savedSearchesAdapter);
        mSearchSectionAdapter.addView(trendsTitle);
        mSearchSectionAdapter.addAdapter(trendsAdapter);
        mSearchSectionList.setAdapter(mSearchSectionAdapter);
    }

    /**
     * 辅助计算位置的类
     * 
     * @author jmx
     * 
     */
    class PositionHelper {
        /**
         * 返回指定位置属于哪一个小节
         * 
         * @param position
         *            绝对位置
         * @return 小节的序号，0是第一小节，1是第二小节, -1为无效位置
         */
        public int getSectionIndex(int position) {
            int[] contentLength = new int[2];
            contentLength[0] = savedSearchesAdapter.getCount();
            contentLength[1] = trendsAdapter.getCount();

            if (position > 0 && position < contentLength[0] + 1) {
                return 0;
            } else if (position > contentLength[0] + 1
                    && position < (contentLength[0] + contentLength[1] + 1) + 1) {
                return 1;
            } else {
                return -1;
            }
        }

        /**
         * 返回指定位置在自己所在小节的相对位置
         * 
         * @param position
         *            绝对位置
         * @return 所在小节的相对位置，-1为无效位置
         */
        public int getRelativePostion(int position) {
            int[] contentLength = new int[2];
            contentLength[0] = savedSearchesAdapter.getCount();
            contentLength[1] = trendsAdapter.getCount();

            int sectionIndex = getSectionIndex(position);
            int offset = 0;
            for (int i = 0; i < sectionIndex; ++i) {
                offset += contentLength[i] + 1;
            }
            return position - offset - 1;
        }
    }

    /**
     * flag: loading;network error;success
     */
    PositionHelper pos_helper = new PositionHelper();

    private void refreshSearchSectionList(int flag) {

        AdapterView.OnItemClickListener searchSectionListListener = new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view,
                    int position, long id) {
                MergeAdapter adapter = (MergeAdapter) (adapterView.getAdapter());
                SearchAdapter subAdapter = (SearchAdapter) adapter
                        .getAdapter(position);

                // 计算针对subAdapter中的相对位置
                int relativePos = pos_helper.getRelativePostion(position);

                SearchItem item = (SearchItem) (subAdapter.getItem(relativePos));
                initialQuery = item.query;
                startSearch();
            }
        };

        if (flag == SearchActivity.LOADING) {
            mSearchSectionList.setOnItemClickListener(null);
            savedSearch.clear();
            trends.clear();
            savedSearchesAdapter.refresh(getString(R.string.search_loading));
            trendsAdapter.refresh(getString(R.string.search_loading));
        } else if (flag == SearchActivity.NETWORKERROR) {
            mSearchSectionList.setOnItemClickListener(null);
            savedSearch.clear();
            trends.clear();
            savedSearchesAdapter
                    .refresh(getString(R.string.login_status_network_or_connection_error));
            trendsAdapter
                    .refresh(getString(R.string.login_status_network_or_connection_error));
        } else {
            savedSearchesAdapter.refresh(savedSearch);
            trendsAdapter.refresh(trends);
        }

        if (flag == SearchActivity.SUCCESS) {
            mSearchSectionList
                    .setOnItemClickListener(searchSectionListListener);
        }
    }

    protected boolean startSearch() {
        if (!TextUtils.isEmpty(initialQuery)) {
            // 以下这个方法在7可用，在8就报空指针
            // triggerSearch(initialQuery, null);
            Intent i = new Intent(this, SearchResultActivity.class);
            i.putExtra(SearchManager.QUERY, initialQuery);
            startActivity(i);
        } else if (TextUtils.isEmpty(initialQuery)) {
            Toast.makeText(this,
                    getResources().getString(R.string.search_box_null),
                    Toast.LENGTH_SHORT).show();
            return false;
        }
        return false;
    }

    // 搜索框回车键判断
    private View.OnKeyListener enterKeyHandler = new View.OnKeyListener() {
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_ENTER
                    || keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
                if (event.getAction() == KeyEvent.ACTION_UP) {
                    initialQuery = mSearchEdit.getText().toString();
                    startSearch();
                }
                return true;
            }
            return false;
        }
    };

    private class TrendsAndSavedSearchesTask extends GenericTask {
        Trend[] trendsList;
        List<SavedSearch> savedSearchsList;

        @Override
        protected TaskResult _doInBackground(TaskParams... params) {
            try {
                trendsList = getApi().getTrends().getTrends();
                savedSearchsList = getApi().getSavedSearches();
            } catch (HttpException e) {
                Log.e(TAG, e.getMessage(), e);
                return TaskResult.IO_ERROR;
            }

            trends.clear();
            savedSearch.clear();

            for (int i = 0; i < trendsList.length; i++) {
                SearchItem item = new SearchItem();
                item.name = trendsList[i].getName();
                item.query = trendsList[i].getQuery();
                trends.add(item);
            }
            for (int i = 0; i < savedSearchsList.size(); i++) {
                SearchItem item = new SearchItem();
                item.name = savedSearchsList.get(i).getName();
                item.query = savedSearchsList.get(i).getQuery();
                savedSearch.add(item);
            }

            return TaskResult.OK;
        }

    }

}

class SearchItem {
    public String name;
    public String query;
}

class SearchAdapter extends BaseAdapter {
    protected ArrayList<SearchItem> mSearchList;
    private Context mContext;
    protected LayoutInflater mInflater;
    protected StringBuilder mMetaBuilder;

    public SearchAdapter(Context context) {
        mSearchList = new ArrayList<SearchItem>();
        mContext = context;
        mInflater = LayoutInflater.from(mContext);
        mMetaBuilder = new StringBuilder();
    }

    public SearchAdapter(Context context, String prompt) {
        this(context);
        refresh(prompt);
    }

    public void refresh(ArrayList<SearchItem> searchList) {
        mSearchList = searchList;
        notifyDataSetChanged();
    }

    public void refresh(String prompt) {
        SearchItem item = new SearchItem();
        item.name = prompt;
        item.query = null;

        mSearchList.clear();
        mSearchList.add(item);

        notifyDataSetChanged();
    }

    @Override
    public int getCount() {
        return mSearchList.size();
    }

    @Override
    public Object getItem(int position) {
        return mSearchList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view;
        if (convertView == null) {
            view = mInflater.inflate(R.layout.search_section_view, parent,
                    false);
            TextView text = (TextView) view
                    .findViewById(R.id.search_section_text);
            view.setTag(text);
        } else {
            view = convertView;
        }

        TextView text = (TextView) view.getTag();

        SearchItem item = mSearchList.get(position);
        text.setText(item.name);

        return view;
    }
}
